package gu.simplemq;

import java.util.Map;
import java.util.Set;

/**
 * 创建消息系统(message queue)实例的工厂接口,实现对消息系统(message queue)的抽象定义
 * @author guyadong
 *
 */
public interface IMessageQueueFactory extends IMQConnParameterSupplier,AutoCloseable{
	/**
	 * 用指定的参数初始化消息系统,只需要调用一次，初始化成功后第二次调用无效
	 * @param properties
	 * @return 当前对象
	 */
	@SuppressWarnings("rawtypes")
	IMessageQueueFactory init(Map properties);
	/**
	 * 用指定的参数初始化消息系统,只需要调用一次，初始化成功后第二次调用无效
	 * @param supplier 消息系统参数提供者对象
	 * @return 当前对象
	 */
	IMessageQueueFactory init(IMQConnParameterSupplier supplier);
	/**
	 * 用指定的参数初始化消息系统,只需要调用一次，初始化成功后第二次调用无效
	 * @param json JSON 格式的参数字符串
	 * @return 当前对象
	 */
	IMessageQueueFactory init(String json);
	/**
	 * @return 当前对象已经初始化返回true,否则返回false
	 */
	boolean initialized();
	/**
	 * 检查当前实例是否初始化,没有初始化抛出异常
	 * @return 当前对象
	 * @throws IllegalStateException  当前对象没有初始化
	 */
	IMessageQueueFactory checkInitialized();
	/**
	 * 设置当前对象为{@link MessageQueueFactorys}的默认实例
	 * @return 当前对象
	 */
	IMessageQueueFactory asDefaultFactory();
	/**
	 * 创建连接池实例
	 * @param name 连接池名称
	 * @param props 连接池参数
	 * @since 2.4.0
	 */
	@SuppressWarnings("rawtypes")
	void definePool(String name, Map props);
	/**
	 * 在指定的连接池中返回订阅器实例<br>
	 * 连接池名字必须是{@link #definePool(String, Map)}已经的名字
	 * @param name 连接池名称
	 * @return {@link ISubscriber}实例
	 * @since 2.4.0
	 */
	ISubscriber getSubscriber(String name);
	/**
	 * 在指定的连接池中返回发布器实例<br>
	 * 连接池名字必须是{@link #definePool(String, Map)}已经的名字
	 * @param name 连接池名称
	 * @return {@link IPublisher}实例
	 * @since 2.5.0
	 */
	IPublisher getPublisher(String name);
	/**
	 * 在指定的连接池中返回消费者实例<br>
	 * 连接池名字必须是{@link #definePool(String, Map)}已经的名字
	 * @param name 连接池名称
	 * @return {@link IConsumer}实例
	 * @since 2.5.0
	 */
	IConsumer getConsumer(String name);
	/**
	 * 在指定的连接池中返回生产者实例<br>
	 * 连接池名字必须是{@link #definePool(String, Map)}已经的名字
	 * @param name 连接池名称
	 * @return {@link IProducer}实例
	 * @since 2.5.0
	 */
	IProducer getProducer(String name);
	/**
	 * 返回订阅器实例
	 * @return {@link ISubscriber}实例
	 */
	ISubscriber getSubscriber();
	/**
	 * 返回消息发布器实例
	 * @return {@link IPublisher}
	 */
	IPublisher getPublisher();
	/**
	 * 返回生产者实例
	 * @return {@link IProducer}
	 */
	IProducer getProducer();
	
	/**
	 * 返回消费者实例
	 * @return {@link IConsumer}
	 */
	IConsumer getConsumer();

	@Override
	MessageQueueType getImplType();
	/**
	 * @return 返回当前工厂实例的初始化参数
	 */
	@Override
	Map<String, Object> getMQConnParameters();
	
	/**
	 * 测试当前连接参数是否可连通
	 * @return 如果可连接返回{@code true},否则返回{@code false}
	 */
	public boolean testConnect();
	/**
	 * 测试指定的连接参数是否可连通
	 * @param props 连接参数
	 * @param timeoutMills 连接超时(毫秒)
	 * @return 连接成功返回{@code true}
	 * @since 2.4.0
	 */
	@SuppressWarnings("rawtypes")
	boolean testConnect(Map props, Long timeoutMills);
	/**
	 * 为消息发布对象({@link IProducer})指定订阅者/消息者数量获取接口实例<br>
	 * 对于不支持获取订阅者/消息者数量的实现中可以通过此接口添加实现
	 * @param advisor
	 * @return 当前对象
	 */
	IMessageQueueFactory setAdvisor(IAdvisor advisor);
	/**
	 * 返回工厂实例支持的协议名称(小写),如{@code 'mqtt'}
	 * @since 2.4.0
	 */
	String getProtocol();
	/**
	 * 返回工厂实例支持的URI scheme名称(小写)的非空集合,如{@code 'mqtt', 'mqtt+ssl'}<br>
	 * 返回集合中至少包含一个元素，即{@link #getProtocol()}返回的协议名称
	 * @since 2.4.0
	 */
	Set<String> getSupportedUriSchemes();
}
